"""
Case Type   : 小型化
Case Name   : 执行安装失败卸载之后重新安装
Create At   : 2024/8/7
Owner       : qumin
Description :
    1.获取安装包并解压
    2.更改属主
    3.执行安装失败卸载之后重新安装
    4.清理数据环境
Expect      :
    1.成功
    2.成功
    3.成功
    4.清理完成
History     :
"""

import os
import unittest
import time
from testcase.utils.Common import Common
from testcase.utils.Common import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class Lite(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_root = Node('PrimaryRoot')
        self.pri_node = Node('PrimaryDbUser')
        self.common = Common()
        self.constant = Constant()
        self.home_path = (os.path.dirname(macro.DB_PKG_PATH))
        self.pkg_path = os.path.join(self.home_path, 'pkg_path')
        self.install_path = os.path.join(self.home_path, 'install_path')
        self.data_path = os.path.join(self.home_path, 'data_path')
        self.u_name = 'u_install_0031'
        self.env_path = os.path.join('/home', self.u_name, '.bashrc')
        self.assert_msg1 = f'start datanode success'
        self.assert_msg2 = f'the parameter -C|--dn-guc[replconninfo=value] ' \
                          f'can not be empty'

    def test_upgrade(self):
        text = '----查询系统未使用端口----'
        self.log.info(text)
        port = self.common.get_not_used_port(self.pri_root)
        self.log.info(port)

        text = '----创建数据库用户和用户组;expect:创建成功----'
        self.log.info(text)
        self.common.create_user(self.pri_root, self.u_name)

        text = '----创建数据，安装包等目录;expect:创建成功----'
        self.log.info(text)
        for d in (self.data_path, self.install_path, self.pkg_path):
            mkdir_cmd = f'if [ ! -d "{d}" ]; then mkdir -p "{d}"; \
                        echo "创建成功，目录已存在";' \
                        f'else echo "目录已存在无需创建"; rm -rf {d}/*; fi'
            result1 = self.common.get_sh_result(self.pri_root, mkdir_cmd)
            self.assertIn('目录已存在', result1, '执行失败:' + text)

        text = '----step1:获取数据库安装包并解压;expect:成功----'
        self.log.info(text)
        cp_cmd = f'cd {macro.DB_PKG_PATH}; ' \
                 f'cp -r openGauss-Lite-*.tar.gz {self.pkg_path};'
        cp_res = self.common.get_sh_result(self.pri_root, cp_cmd)
        ls_cmd = f"ls {self.pkg_path}|grep -E '*Lite.*tar.gz'"
        file_name = self.common.get_sh_result(self.pri_root, ls_cmd)
        tar_cmd = f'cd {self.pkg_path};tar -xf {file_name}'
        self.log.info(tar_cmd)
        tar_res = self.common.get_sh_result(self.pri_root, tar_cmd)
        ls_res = self.common.get_sh_result(self.pri_root,
                                           f'ls -l {self.pkg_path}')
        self.assertIn('install.sh', ls_res, '执行失败:' + text)

        text = '----step2:root用户修改安装包解压目录、安装目录、数据目录的路径权限和属主;expect:修改成功----'
        self.log.info(text)
        file_own = f'chown -R {self.u_name}:{self.u_name} ' \
                   f'{self.install_path} {self.data_path} ' \
                   f'{self.pkg_path};'
        self.log.info(file_own)
        file_msg = self.common.get_sh_result(self.pri_root, file_own)
        self.log.info(file_msg)
        self.assertEqual('', file_msg, '执行失败：' + text)

        chm_cmd = f'chmod -R 755 {self.install_path} {self.data_path} ' \
                  f'{self.pkg_path};'
        self.log.info(chm_cmd)
        chm_result = self.common.get_sh_result(self.pri_root, chm_cmd)
        self.assertEqual('', chm_result, '执行失败：' + text)

        text = '----step3:执行安装失败卸载之后重新安装;expect:安装成功----'
        self.log.info(text)
        text = '----step3.1:执行安装;expect:安装失败----'
        self.log.info(text)
        su_cmd = f'su - {self.u_name}'
        install_cmd = f'cd {self.pkg_path}; sh install.sh ' \
                      f'-D {self.data_path} ' \
                      f'-R {self.install_path} ' \
                      f'--mode primary -C port={port} ' \
                      f'--start;' \
                      f'source {self.env_path}'
        execute_cmd = f'''expect <<EOF
                        spawn {su_cmd}
                        expect "$"
                        send "{install_cmd}\\n"
                        expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.pri_root, execute_cmd)
        self.assertIn(self.assert_msg2, execute_msg, '执行失败' + text)

        text = '----step3.2:执行卸载脚本;expect:成功----'
        self.log.info(text)
        uninstall_cmd = f'su - {self.u_name} -c "cd {self.pkg_path}&&' \
                        f'sh uninstall.sh --delete-data"&& ' \
                        f'sed -i \'/export/d\' {self.env_path} && ' \
                        f'source {self.env_path}'
        uninstall_msg = self.common.get_sh_result(self.pri_root, uninstall_cmd)
        self.log.info(uninstall_msg)
        self.assertIn('clean up related processes success',
                      uninstall_msg, '执行失败' + text)

        text = '----step3.3:再次执行安装;expect:安装成功----'
        self.log.info(text)
        su_cmd = f'su - {self.u_name}'
        install_cmd = f'cd {self.pkg_path}; sh install.sh ' \
                      f'-D {self.data_path} ' \
                      f'-R {self.install_path} ' \
                      f'--mode single -C port={port} ' \
                      f'--start;' \
                      f'source {self.env_path}'
        execute_cmd = f'''expect <<EOF
                                spawn {su_cmd}
                                expect "$"
                                send "{install_cmd}\\n"
                                expect "input sql password:"
                                send "{macro.COMMON_PASSWD}\\n"
                                expect "input sql password:"
                                send "{macro.COMMON_PASSWD}\\n"
                                expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.pri_root, execute_cmd)
        self.assertIn(self.assert_msg1, execute_msg, '执行失败' + text)

    def tearDown(self):
        text = '----step4:执行卸载脚本，并清理环境;expect:成功----'
        self.log.info(text)
        uninstall_cmd = f'su - {self.u_name} -c "cd {self.pkg_path}&&' \
                        f'sh uninstall.sh --delete-data"&& ' \
                        f'sed -i \'/export/d\' {self.env_path} && ' \
                        f'source {self.env_path};chmod 755 {self.home_path};'
        uninstall_msg = self.common.get_sh_result(self.pri_root, uninstall_cmd)
        self.log.info(uninstall_msg)
        rm_cmd = f'rm -rf {self.install_path} {self.data_path} ' \
                 f'{self.pkg_path};'
        self.log.info(rm_cmd)
        rm_result = self.common.get_sh_result(self.pri_root, rm_cmd)
        self.log.info(rm_result)
        del_cmd = f'userdel -r {self.u_name}'
        del_result = self.common.get_sh_result(self.pri_root, del_cmd)
        self.log.info(del_result)
        self.assertIn('clean up related processes success',
                      uninstall_msg, '执行失败' + text)
        self.assertEqual('', rm_result, '执行失败:' + text)
        self.assertEqual('', del_result, '删除用户失败:' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
